package com.yunshan.system.controller;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yunshan.common.core.controller.BaseController;
import com.yunshan.common.core.domain.AjaxResult;
import com.yunshan.common.utils.JsonUtils;
import com.yunshan.system.utils.JwtUtil;
import com.yunshan.wechat.domain.WechatUserInfo;
import com.yunshan.wechat.service.IWechatUserInfoService;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static com.yunshan.framework.datasource.DynamicDataSourceContextHolder.log;


/**
 * 微信小程序用户接口
 * @author admin001
 */
@Api(tags = "小程序登录")
@RestController
@RequestMapping("/api/auth")
public class AuthController extends BaseController {

    @Autowired
    private WxMaService wxMaService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private IWechatUserInfoService userInfoService;
    @Autowired
    private JwtUtil jwtUtil;

    @ApiOperation("登录")
    @PostMapping("/login")
    public AjaxResult login(
            @RequestBody Map<String,String> map
                                   ) {
        try {
            // 换取 openid 和 session_key
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(map.get("code"));
            log.info("session：{}",session.toString());

            String openid = session.getOpenid();
            String sessionKey = session.getSessionKey();
            String unionId = session.getUnionid();

            //解密手机号
            WxMaPhoneNumberInfo phoneInfo = wxMaService.getUserService().getPhoneNoInfo(sessionKey, map.get("encryptedData"),map.get("iv"));
            log.info("手机号：{}",phoneInfo.toString());

            //查询用户信息,不存在则新增
            WechatUserInfo wechatUserInfo = userInfoService.selectWechatUserInfo(openid, unionId, phoneInfo.getPhoneNumber());
            log.info("用户信息：{}",wechatUserInfo.toString());

            // 生成双 Token
            String accessToken = jwtUtil.generateAccessToken(wechatUserInfo.getId(), openid, unionId);
            String refreshToken = jwtUtil.generateRefreshToken(openid);

            redisTemplate.opsForValue().set(
                    "refresh:" + refreshToken,
                    refreshToken
            );

            //存储sessionKey，有效期为2小时
            redisTemplate.opsForValue().set(
                    "session_key:" + openid,
                    sessionKey,
                    2, TimeUnit.HOURS
            );

            // 返回 Token
            Map<String, String> response = new HashMap<>();
            response.put("accessToken", accessToken);
            response.put("refreshToken", refreshToken);
            return success(response);

        } catch (Exception e) {
            log.error("登录失败：{}", e.toString());
            return error("登录失败，" + e.getMessage());
        }
    }


    /**
     *
     * @param refreshToken 刷新令牌
     * @return 令牌
     */
    @ApiOperation("刷新令牌")
    @PostMapping("/refresh-token")
    public AjaxResult refreshToken(@RequestBody String refreshToken) {
        try {
            // 1. 验证 Refresh Token 有效性
            String refresh = new ObjectMapper().readTree(refreshToken).get("refreshToken").asText();
            if (Boolean.FALSE.equals(redisTemplate.hasKey("refresh:" + refresh))) {
                return error("重新登录失败");
            }

            Claims claims = jwtUtil.parseToken(refresh);
            String openid = claims.getSubject();

            //查询用户信息
            WechatUserInfo wechatUserInfo = userInfoService.selectWechatUserInfoByOpenid(openid);
            log.info("用户信息：{}",wechatUserInfo.toString());

            // 2. 生成新双 Token
            String newAccessToken = jwtUtil.generateAccessToken(wechatUserInfo.getId(), openid, wechatUserInfo.getUnionId());
            String newRefreshToken = jwtUtil.generateRefreshToken(openid);

            // 3. 更新 Redis
            redisTemplate.delete("refresh:" + refresh); // 使旧 Token 失效
            redisTemplate.opsForValue().set(
                    "refresh:" + newRefreshToken,
                    newRefreshToken
            );

            // 4. 返回新 Token
            Map<String, String> response = new HashMap<>();
            response.put("accessToken", newAccessToken);
            response.put("refreshToken", newRefreshToken);
            return success(response);
        } catch (Exception e) {
            log.error("Token 刷新失败：{}", e.toString());
            return error("重新登录失败");
        }
    }

}
